console.log('开始监控性能')
let FCPTime:unknown = null
let TTITime:unknown=null
// 重排检测
const layoutPerformance = new PerformanceObserver(list => {
  list.getEntries().forEach(entry => {
    if (entry.entryType === 'layout-shift') {
      //   console.log('发生了重排')
    }
  })
})
layoutPerformance.observe({ type: 'layout-shift', buffered: true })

// 重绘检测
const paintPerformance = new PerformanceObserver(list => {
  list.getEntries().forEach(entry => {
    if (entry.entryType === 'paint') {
      // console.log('发生了重绘',entry)
    }
  })
})
paintPerformance.observe({
  type: 'paint',
  buffered: true,
  durationThreshold: 16,
})

// 资源监测
const resourcePerformance = new PerformanceObserver(list => {
  for (const entry of list.getEntries()) {
    // 检查 entry 类型是否为我们关注的 'resource'
    if (entry.entryType === 'resource') {
      //   console.log(`${entry.name}(${entry.duration}ms)-${entry.initiatorType}`);
    }
  }
})
resourcePerformance.observe({ type: 'resource' })

// fetch请求监测
const fetchPreformance = new PerformanceObserver(list => {
  for (const entry of list.getEntries()) {
    if (entry.entryType === 'resource' && entry.initiatorType === 'fetch') {
      console.log(`fetch请求 ${entry.name} took ${entry.duration} ms`)
    }
  }
})
fetchPreformance.observe({ type: 'resource' })

//长任务检测
const longTaskPreformance = new PerformanceObserver(list => {
  for (const entry of list.getEntries()) {
    if (entry.entryType === 'longtask') {
      //   console.log(`发现了长任务: ${entry.duration} ms`)
    }
  }
})
longTaskPreformance.observe({ type: 'longtask' })

// 页面参数检测
const pagePerformanceObserver = new PerformanceObserver(list => {
  // PerformanceObserverEntryList 对象
  const entries = list.getEntries()
  for (let entry of entries) {
    // console.log('page', entry)
  }
})
pagePerformanceObserver.observe({
  type: 'navigation',
  buffered: true,
})

// inp时间
const inPobserver = new PerformanceObserver(list => {
  const entries = list.getEntries()
  let inpTime = 0
  // 将所有的事件耗时进行统计，取最大耗时
  for (const entry of entries) {
    //   const inputDelay = entry.processingStart - entry.startTime
    //   const processingTime = entry.processingEnd - entry.processingStart
    //   const eventType = entry.name
    //   console.log(processingTime,eventType)
    const duration = entry.duration
    inpTime = Math.max(inpTime, duration)
  }
  // INP 时间
  console.log('INP时间' + inpTime)
})
inPobserver.observe({
  type: 'event',
  buffer: true,
  durationThreshold: 50,
})

// FCP，LCP，CLS
const FLCPerformance = new PerformanceObserver(list => {
  list.getEntries().forEach(entry => {
    switch (entry.entryType) {
      case 'paint':
        if (entry.name === 'first-contentful-paint') {
            console.log('FCP', entry.startTime, 'ms')
            FCPTime=entry.startTime
        }
        break
      case 'largest-contentful-paint':
        console.log('LCP', entry.renderTime, 'ms', entry.element)
        break
      case 'layout-shift':
        if (!entry.hadRecentInput) {
          console.log('CLS', entry.value)
        }
        break
    }
  })
})
FLCPerformance.observe({
  entryTypes: ['paint', 'largest-contentful-paint', 'layout-shift'],
})

// 检测每一帧的时间
const animObserver = new PerformanceObserver((list, observer) => {
  const entries = list.getEntries()
  for (let entry of entries) {
    // 如果帧渲染时间超过 16ms，说明可能存在性能问题
    if (entry.duration > 16) {
      console.warn('超过16ms:', entry.duration, 'ms')
      // 这里可以添加更多的调试信息或采取优化措施
    }
  }
})
animObserver.observe({ type: 'long-animation-frame', buffered: true })

// first-input:首次点击的全部信息用户第一次与网页进行交互（如点击链接、按钮等）到浏览器实际开始处理该操作之间的延迟时间
const fiPerformanceObserver = new PerformanceObserver(list => {
  const entries = list.getEntries()
  for (let entry of entries) {
    console.log('first-input', entry.duration, entry.startTime, entry.target)
  }
})
fiPerformanceObserver.observe({
  type: 'first-input',
  buffered: true,
})

// TTI：网页从加载开始到完全可以交互的时间
let firstInteractiveTime = null;
let lastLongTaskTime = 0;
let isInteractive = false;

// 监听 longtask 事件
const observer = new PerformanceObserver((list) => {
    for (const entry of list.getEntries()) {
        if (entry.entryType === 'longtask') {
            lastLongTaskTime = entry.startTime + entry.duration;
        }
    }

    // 检查是否达到了 TTI
    if (!isInteractive && isPageInteractive()) {
        isInteractive = true;
        firstInteractiveTime = lastLongTaskTime || performance.now();
        console.log('Time to Interactive:', firstInteractiveTime);
        TTITime=firstInteractiveTime
        observer.disconnect(); // 停止监听 longtask 事件
    }
});

observer.observe({ type: 'longtask', buffered: true });

// 监听 load 事件
window.addEventListener('load', () => {
    checkPageInteractive();
});

// 监听 visibilitychange 事件
document.addEventListener('visibilitychange', () => {
    if (document.visibilityState === 'visible') {
        checkPageInteractive();
    }
});

// 检查页面是否可交互
function checkPageInteractive() {
    if (!isInteractive && isPageInteractive()) {
        isInteractive = true;
        firstInteractiveTime = lastLongTaskTime || performance.now();
        console.log('Time to Interactive:', firstInteractiveTime);
        observer.disconnect();
    }
}

// 判断页面是否达到可交互状态
function isPageInteractive() {
    return (
        document.readyState === 'complete' && 
        document.visibilityState === 'visible' &&
        performance.getEntriesByType('paint').some(entry => entry.name === 'first-contentful-paint') &&
        !hasLongTasks()
    );
}

// 检查是否有长任务
function hasLongTasks() {
    const longTasks = performance.getEntriesByType('longtask');
    return longTasks.length > 0 && longTasks.some(task => task.startTime + task.duration > performance.now());
}

// 初始检查页面是否已经可交互
if (isPageInteractive()) {
    isInteractive = true;
    firstInteractiveTime = performance.now();
    console.log('Time to Interactive:', firstInteractiveTime);
    observer.disconnect();
}

// TBT FCP到TTI之间长任务的时间
const TBTObserver = new PerformanceObserver((list, observer) => {
    let totalBlockingTime = 0;
  const entries = list.getEntries();
  for (const entry of entries) {
    if (FCPTime && TTITime && entry.startTime >= FCPTime && entry.startTime < TTITime) {
      totalBlockingTime += entry.duration;
    }
  }
    console.log('TBT',totalBlockingTime)
});
TBTObserver.observe({ entryTypes: ['longtask'] });
